#include "dbusargv.hpp"
#include "common.hpp"


bool getTypeByDBusArg(QString DBusArgs, int &ctype, QString &typeName)
{
    if(DBusArgs.startsWith ("a{"))
    {
        typeName = "dict";
        ctype = qMetaTypeId<dict>();

    }else if(DBusArgs.startsWith ("("))
    {
        typeName = "struct";
        ctype = qMetaTypeId<structs>();

    }else if(DBusArgs.startsWith ("ay"))
    {
        typeName = "Bytes";
        ctype = qMetaTypeId<QByteArray>();
    }else if(DBusArgs.startsWith ("a"))
    {
        typeName = "array";
        ctype = qMetaTypeId<array>();
//        buildList();
    }else if(DBusArgs.startsWith ("y"))
    {
        ctype = QMetaType::Char;
        typeName = "Byte";

    }else if(DBusArgs.startsWith ("b"))
    {
        ctype = QMetaType::Bool;
        typeName = "Bool";
    }else if(DBusArgs.startsWith ("n"))
    {
        ctype = QMetaType::Short;
        typeName = "Int16";

    }else if(DBusArgs.startsWith ("q"))
    {
        ctype = QMetaType::UShort;
        typeName = "UInt16";

    }else if(DBusArgs.startsWith ("i"))
    {
        ctype = QMetaType::Int;
        typeName = "Int32";

    }else if(DBusArgs.startsWith ("u"))
    {
        ctype = QMetaType::UInt;
        typeName = "UInt32";

    }else if(DBusArgs.startsWith ("x"))
    {
        ctype = QMetaType::LongLong;

    }else if(DBusArgs.startsWith ("t"))
    {
        ctype = QMetaType::ULongLong;
        typeName = "UInt64";
    }else if(DBusArgs.startsWith ("d"))
    {
        ctype = QMetaType::Double;
        typeName = "double";
    }else if(DBusArgs.startsWith ("s"))
    {
        ctype = QMetaType::QString;
        typeName = "string";
    }else if(DBusArgs.startsWith ("o"))
    {
        ctype = qMetaTypeId<QDBusObjectPath>();
        typeName = "DBusPath";
    }else if(DBusArgs.startsWith ("g"))
    {
        ctype = qMetaTypeId<QDBusSignature>();
        typeName = "DBusSignal";
    }else if(DBusArgs.startsWith ("h"))
    {
        ctype = qMetaTypeId<QDBusUnixFileDescriptor>();
        typeName = "UNIX_FD";
    }else if(DBusArgs.startsWith ("v"))
    {
        ctype = qMetaTypeId<QDBusVariant>();
        typeName = "Variant";
    }else
    {
        ctype = QMetaType::UnknownType;
        typeName = "UnknownType";
    }
    return true;
}

int getNextType(QString DBusArgs,QString &Value,QString &out)
{
    QString basetyes ="ybnqiuxtdsoghv";
    if(DBusArgs.isEmpty ())
    {
        return Flag_ERROR_EMPTY;
    }
    QChar var = DBusArgs.at (0);
    if(basetyes.contains (var))
    {
        Value = DBusArgs.left (1);
        out = DBusArgs.mid (1);
        return Flag_BASE_SUCCESS;
    }else if(DBusArgs.startsWith ("ay"))
    {
        Value = DBusArgs.left (2);
        out = DBusArgs.mid (2);
        return Flag_BASE_SUCCESS;
    }else if(DBusArgs.startsWith ("a{"))
    {
        Value.append ("a{");
        QString keys="";
        QString Values="";
        out = DBusArgs.mid (2);
        if(!getNextType(out,keys,out))
        {
            return Flag_ERROR_DICT_KEY;
        }
        if(!getNextType(out,Values,out))
        {
            return Flag_ERROR_DICT_VALUE;
        }

        Value.append (keys);
        Value.append (Values);
        Value.append ("}");
        if(out.startsWith ("}"))
        {
            out= out.mid (1);
            return Flag_DICT_SUCCESS;
        }
    }else if(DBusArgs.startsWith ("a"))
    {
        Value.append ("a");
        QString Values="";
        out = DBusArgs.mid (1);
        if(getNextType(out,Values,out))
        {
            Value.append (Values);
        }else
        {
            return Flag_ERROR_ARRAY_VALUE;
        }
        return Flag_ARRAY_SUCCESS;
    }else if(DBusArgs.startsWith ("("))
    {
        Value.append ("(");
        QString keys="";
        QString Values="";
        out = DBusArgs.mid (1);
        while (!out.startsWith (")")) {
            if(getNextType(out,Values,out))
            {
                Value.append (Values);
                if(out.length ()==0)
                {
                    return Flag_ERROR_STRUCT;
                }
            }else
            {
                return Flag_ERROR_STRUCT;
            }
        }
        Value.append (")");
        out = out.mid (1);
        return Flag_STRUCT_SUCCESS;
    }
    return false;
}
